package co.baiku.boot.core.orm.service.impl;

import co.baiku.boot.common.exception.ApiException;
import co.baiku.boot.core.orm.dao.BaseDAO;
import co.baiku.boot.core.orm.po.TenantPo;
import co.baiku.boot.core.orm.service.BaseService;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.HttpStatus;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public abstract class TenantBaseServiceImpl<T extends TenantPo, D, ID extends Serializable> extends BaseServiceImpl<T, D, ID> implements BaseService<T, D, ID> {
    protected final String DEL = "EQ_del";
    protected final String TENANT = "EQ_tenantId";

    public TenantBaseServiceImpl(BaseDAO<T, ID> baseDAO) {
        super(baseDAO);
    }

    public abstract Long getTenantId();

    @Override
    public List<T> findAll() {
        Map<String, Object> search = new HashMap<>();
        search.put(DEL, false);
        search.put(TENANT, getTenantId());
        return findAll(search);
    }

    @Override
    public List<T> findByProperty(String property, Object value, Map<String, String> sort) {
        Map<String, Object> searchParams = new HashMap<>();
        searchParams.put(property, processQueryField(property, value));
        searchParams.put(DEL, false);
        searchParams.put(TENANT, getTenantId());
        return findAll(searchParams, sort);
    }


    @Override
    public T getById(ID id) {
        if (id == null) {
            return null;
        }
        T result = baseDAO.getById(id);
        Long tenantId = getTenantId();
        if (result != null && result.getDel() || (tenantId != null && result != null && !tenantId.equals(result.getTenantId()))) {
            return null;
        }
        return result;
    }

    @Override
    public T saveOrUpdate(T entity) {
        if (entity == null) {
            return null;
        }
        if (entity.getDel() == null) {
            entity.setDel(false);
        }
        if (entity.getTenantId() == null) {
            entity.setTenantId(getTenantId());
        }
        return baseDAO.saveAndFlush(entity);
    }

    @Override
    public void delete(T entity) {
        if (entity.getTenantId() != null && !getTenantId().equals(getTenantId())) {
            throw ApiException.of(HttpStatus.BAD_REQUEST, 401, "无权删除");
        }
        super.delete(entity);
    }

    /**
     * 拼装del参数
     *
     * @return 动态查询条件
     */
    @Override
    public Specification<T> logicDeleteRequisite() {
        Map<String, Object> searchParams = new HashMap<>();
        searchParams.put(DEL, false);
        searchParams.put(TENANT, getTenantId());
        return buildSpecification(searchParams);
    }
}
